# -*- coding: utf-8 -*-

__author__ = """WebLion <support@weblion.psu.edu>"""
__docformat__ = 'plaintext'

#
# Test-cases for Contacts Directory portal tool
#

from Products.ContactsDirectory.config import *
from Products.ContactsDirectory.tests.testPlone import testPlone
from Products.CMFCore.utils import getToolByName
from Products.membrane.config import TOOLNAME as MEMBRANE_TOOL

class testContactsDirectoryTool(testPlone):
    """Test-cases for ContactsDirectoryTool."""

    def afterSetUp(self):
        from Products.CMFCore.utils import getToolByName
        from Products.ContactsDirectory.config import TOOLNAME
        
        self.loginAsPortalOwner()
        self.directory = self.getPopulatedDirectory()
        self.person = self.getPerson(id='abc123', firstName="Test", lastName="Person")
        self.cd_tool = getToolByName(self.person,TOOLNAME)
        # set up an additional, non-cd user for testing folder and profile methods
        self.portal.acl_users._doAddUser('user1','secret',['Member'],[])
        self.mt = getToolByName(self.person,'portal_membership')
        
    def testUseInternalPasswordControlsAuth(self):
        from Products.membrane.interfaces import IUserAuthentication
        
        u = IUserAuthentication(self.person)
        self.person.setPassword("chewy1")
        if self.cd_tool.getUseInternalPassword():
            self.failUnless(u.verifyCredentials({'login':'abc123','password':'chewy1'}),"useInternalPassword appears to be broken, failed to verify correct login and password: %s" % self.cd_tool.getUseInternalPassword())
            self.cd_tool.setUseInternalPassword(False)
            self.failIf(u.verifyCredentials({'login':'abc123','password':'chewy1'}), "useInternalPassword not toggled.  verification still allowed: %s" % self.cd_tool.getUseInternalPassword())
        else:
            self.failIf(u.verifyCredentials({'login':'abc123','password':'chewy1'}),"verification allowed, but shouldn't have been: %s" % self.cd_tool.getUseInternalPassword())
            self.cd_tool.setUseInternalPassword(True)
            self.failUnless(u.verifyCredentials({'login':'abc123','password':'chewy1'}), "useInternalPassword not toggled.  verification still disallowed: %s" % self.cd_tool.getUseInternalPassword())
            
    def testIdRegexDefault(self):
        """ Check to make sure the idRegex field is defaulting to the value set in portal_registration
        """
        # get the default value
        self.cd_tool.pre_edit_setup()
        idRegex = self.cd_tool.getIdRegex()
        # get the value from portal_registration
        pr = getToolByName(self.portal, 'portal_registration')
        regPattern = pr.getIDPattern() or pr.getDefaultIDPattern()
        self.failUnless(idRegex == regPattern)
        
    def testIdRegexChecking(self):
        """ Make sure the id regex validation is working
        """
        self.cd_tool.setIdRegex('[A-Z]')
        self.cd_tool.setIdRegexErrorMessage('Not even close.')
        message = self.person.validate_id('123456')
        self.failUnless(message == 'Not even close.')        
        self.failUnless(not self.person.validate_id('ABC'))        
        
    def testRegexValidation(self):
        """ Make sure the value entered is a valid regular expression
        """
        self.failUnless(self.cd_tool.validate_idRegex(']['))
        self.failUnless(not self.cd_tool.validate_idRegex('[A-Za-z]'))

    def testToolForm(self):
        """ We're overriding some things in the base form for this configlet. That causes some issues
            between Plone 2.5 and 3. Make sure it works properly for each. Mostly just AttributeErrors
        """
        self.failUnless(not self.cd_tool.edit())
    
    def testNotInFolderContents(self):
        """ Make sure the tool isn't showing up in the folder contents at the root of the Plone site.
        """
        self.failUnless('contactsdirectory_tool' not in [o.id for o in self.portal.getFolderContents()], 'ContactsDirectory_tool is listed in the folder contents of the portal.')

    def testFTISetup(self):
        """ Make sure the FTI is pulling info from the GS types profile """
        self.failUnless(self.portal.portal_types['CDContactsDirectoryTool'].Title() != "AT Content Type")
    
    def testGetDirectoryRoot(self):
        """Make sure this returns the containing CD."""
        self.failUnlessEqual(self.person.getDirectoryRoot(), self.directory)
        
    def testFsdMyFolder(self):
        """cdMyFolder method should return the appropriate url for non-cd users or 
        for cd users
        """
        self.login(self.person.id)
        # logged in as an cd user, the substring <directory_id/user_id> should be in the  return value for the function
        self.failUnless(self.cd_tool.cdMyFolder().find(self.directory.id + '/' + self.person.id), "bad url returned for %s: %s" % (self.person.id, self.cd_tool.cdMyFolder()))
        
        self.login('user1')
        # set up a memberarea
        if (not self.mt.getMemberareaCreationFlag()):
            self.mt.setMemberareaCreationFlag()
        self.mt.createMemberArea()
        try:
            self.failUnless(self.cd_tool.cdMyFolder().find(self.mt.getMembersFolder().id + '/user1'), "bad url returned for user1: %s" % self.cd_tool.cdMyFolder())
        except IndexError:
            self.fail("Index Error indicates that there are no search results from the membrane tool")
            
    def testFsdMemberProfile(self):
        """cdMemberProfile should return the location of the editor for member profile information.
        This will change depending on whether the member is an cd person or an acl_users member
        """
        self.login(self.person.id)
        # logged in as an cd user, the substring <directory_id/user_id/edit> should be in the return value for the function
        self.failUnless(self.cd_tool.cdMemberProfile().find(self.directory.id + '/' + self.person.id), "bad url returned for %s: %s" % (self.person.id, self.cd_tool.cdMemberProfile()))
        
        # now as an acl_users user
        self.login('user1')
        try:
            self.failUnless(self.cd_tool.cdMemberProfile().find('/personalize_form'), "bad url returned for user1: %s" % self.cd_tool.cdMyFolder())
        except IndexError:
            self.fail("Index Error indicates that there are no search results from the membrane tool")
            
    def testFsdShowMyFolder(self):
        """cdShowMyFolder tries to intelligently decide whether to show the 'my folder' action
        button or not.  It tests to see if a member is an cd person, and acts accordingly
        """
        self.login(self.person.id)
        # logged in as an cd user, the method should always return true
        self.failUnless(self.cd_tool.cdShowMyFolder(), "cdShowMyFolder returning false for cd user")
        
        # now as acl_users user
        self.login('user1')
        try:
            if (self.mt.getMemberareaCreationFlag() and (self.mt.getHomeFolder() is not None)):
                self.failUnless(self.cd_tool.cdShowMyFolder(), "should be showing my folder for acl_users, but we aren't")
            else:
                self.failIf(self.cd_tool.cdShowMyFolder(), "should not be showing my folder for acl_users, but we are")
        except IndexError:
            self.fail("Index Error indicates that there are no search results from the membrane tool")

    def testMembraneTypeDeactivation(self):
        """test that the cd_tool's at_post_edit_script calls the modifyMembraneTypes event and
        that event correctly deals with membrane activation/deactivation
        """
        # Be sure that CDPerson is still a membrane provider, or the test will be invalid
        self.failUnless('CDPerson' in MEMBRANE_ABLE_TYPES, "test invalid, CDPerson is not listed as membrane-able")

        mbt = getToolByName(self.person, MEMBRANE_TOOL)
        uf = getToolByName(self.person, 'acl_users')
        mtypes = mbt.listMembraneTypes()
        new_types_list = tuple(set(MEMBRANE_ABLE_TYPES) - set(('CDPerson',)))

        # CDPerson should be membrane-active at setup
        self.failUnless('CDPerson' in self.cd_tool.getEnableMembraneTypes() and 'CDPerson' in mtypes, "CDPerson should be in both lists: %s, %s" % (self.cd_tool.getEnableMembraneTypes(), mtypes))
        self.failUnless(uf.getUserById('abc123'), "Person 'abc123' not registered as user via acl_users")
        
        # now, let's manually alter the list of types, and simulate editing the tool
        self.cd_tool.setEnableMembraneTypes(new_types_list)
        self.cd_tool.reindexObject()
        self.cd_tool.at_post_edit_script()
        
        # CDPerson should not be membrane-active
        mtypes = mbt.listMembraneTypes()
        self.failIf('CDPerson' in self.cd_tool.getEnableMembraneTypes() or 'CDPerson' in mtypes, "CDPerson should not be in either list: %s, %s" % (self.cd_tool.getEnableMembraneTypes(), mtypes))
        self.failIf(uf.getUserById('abc123'), "Person 'abc123' active as a user after membrane de-activation")
        
        # now, put everything back!
        self.cd_tool.setEnableMembraneTypes(MEMBRANE_ABLE_TYPES)
        self.cd_tool.reindexObject()
        self.cd_tool.at_post_edit_script()
        
        # CDPerson should be membrane-active again
        mtypes = mbt.listMembraneTypes()
        self.failUnless('CDPerson' in self.cd_tool.getEnableMembraneTypes() and 'CDPerson' in mtypes, "CDPerson should be in both lists: %s, %s" % (self.cd_tool.getEnableMembraneTypes(), mtypes))
        self.failUnless(uf.getUserById('abc123'), "Person 'abc123' not active as a user after membrane re-activation")
        
        
def test_suite():
    from unittest import TestSuite, makeSuite
    suite = TestSuite()
    suite.addTest(makeSuite(testContactsDirectoryTool))
    return suite
